#ifndef _YL_MEMORYSTREAM_
#define _YL_MEMORYSTREAM_

#include "ylEssentials.h"
#include <string>

namespace yoctolog
{
	class MemoryStream
	{
	public:
		YL_API MemoryStream(unsigned int uiStartingSize = 1024);
		YL_API MemoryStream(unsigned char *pData, unsigned int uiSize);
		YL_API ~MemoryStream();

		void Clear();

		void Write(const void * pData, int iSize);
		bool ResizeBuffer(unsigned int uiNewSize);

		void WriteToFile(const std::string &strFilename);
		void LoadFromFile(const std::string &strFilename);

		template<typename T>
		void Read(T &val) const
		{
			(*this) >> val;
		}

		template<typename T>
		void operator >>(T &val) const
		{
			val = *(reinterpret_cast<T*>(&m_pData[m_iDataPos]));
			m_iDataPos += sizeof(T);
		}
		YL_API void operator >>(char * &szValue) const;
		YL_API void operator >>(std::string &strValue) const;
		YL_API void operator >>(bool &bValue) const;

		template<typename T>
		void Write(const T &val)
		{
			(*this) << val;
		}
		template<typename T>
		void operator <<(const T &val)
		{
			Write(&val, sizeof(T));
		}
		YL_API void operator <<(const bool &bValue);
		YL_API void operator <<(const char* szValue);
		YL_API void operator <<(char* szValue);
		YL_API void operator <<(const std::string &strValue);

		char *GetData() const { return m_pData; }
		void SetData(char *pData, int iSize) { m_pData = pData; m_iDataSize = iSize; }
		int GetDataSize() const { return m_iDataSize; }
		int GetUsedSize() const { return m_iUsedSize; }
		int GetPos() const { return m_iDataPos; }

	private:
		char *				m_pData;
		int					m_iDataSize;
		int					m_iUsedSize;
		mutable int			m_iDataPos;
	};
}

#endif